const { 
  Connection, 
  Keypair, 
  PublicKey
} = require('@solana/web3.js');

// 靓号地址生成配置
const PRETTY_CONFIG = {
  prefix: '123',      // 前缀
  suffix: '',         // 后缀
  caseSensitive: false, // 不区分大小写
  maxAttempts: 100000   // 最大尝试次数
};

/**
 * 验证地址是否符合靓号要求
 */
function validatePrettyAddress(address, config) {
  const { prefix = '', suffix = '', caseSensitive = false } = config;
  
  if (!prefix && !suffix) return true;
  
  const targetAddress = caseSensitive ? address : address.toLowerCase();
  const targetPrefix = caseSensitive ? prefix : prefix.toLowerCase();
  const targetSuffix = caseSensitive ? suffix : suffix.toLowerCase();
  
  const hasValidPrefix = !prefix || targetAddress.startsWith(targetPrefix);
  const hasValidSuffix = !suffix || targetAddress.endsWith(targetSuffix);
  
  return hasValidPrefix && hasValidSuffix;
}

/**
 * 计算靓号难度
 */
function calculateDifficulty(prefix = '', suffix = '', caseSensitive = false) {
  const prefixLength = prefix.length;
  const suffixLength = suffix.length;
  const totalLength = prefixLength + suffixLength;
  
  if (totalLength === 0) return 1;
  
  // Base58字符集大小
  const charset = caseSensitive ? 58 : 32; // 不区分大小写时减少字符集
  
  // 计算理论尝试次数
  const difficulty = Math.pow(charset, totalLength);
  
  return Math.floor(difficulty);
}

/**
 * 生成靓号地址
 */
async function generatePrettyAddress(config) {
  console.log('🎯 开始生成靓号地址...\n');
  console.log('📊 配置信息:');
  console.log(`- 前缀: "${config.prefix || '无'}"`);
  console.log(`- 后缀: "${config.suffix || '无'}"`);
  console.log(`- 区分大小写: ${config.caseSensitive ? '是' : '否'}`);
  console.log(`- 最大尝试次数: ${config.maxAttempts.toLocaleString()}\n`);
  
  const difficulty = calculateDifficulty(config.prefix, config.suffix, config.caseSensitive);
  console.log(`🎲 理论难度: ${difficulty.toLocaleString()}`);
  console.log(`⏱️  预估时间: ${Math.ceil(difficulty / 20000)} 秒\n`);
  
  const startTime = Date.now();
  let attempts = 0;
  let lastLogTime = startTime;
  
  console.log('🔄 开始生成...');
  
  while (attempts < config.maxAttempts) {
    attempts++;
    
    // 生成新的密钥对
    const keypair = Keypair.generate();
    const address = keypair.publicKey.toString();
    
    // 检查是否符合要求
    if (validatePrettyAddress(address, config)) {
      const timeElapsed = Date.now() - startTime;
      
      console.log('\n🎉 成功生成靓号地址！');
      console.log('=====================================');
      console.log(`📍 地址: ${address}`);
      console.log(`🔑 私钥: [${Array.from(keypair.secretKey).slice(0, 8).join(', ')}...]`);
      console.log(`🎯 尝试次数: ${attempts.toLocaleString()}`);
      console.log(`⏱️  耗时: ${(timeElapsed / 1000).toFixed(2)} 秒`);
      console.log(`🚀 速度: ${Math.round(attempts / (timeElapsed / 1000)).toLocaleString()} 地址/秒`);
      
      // 验证生成的地址
      console.log('\n🔍 验证信息:');
      console.log(`- 前缀匹配: ${!config.prefix || address.toLowerCase().startsWith(config.prefix.toLowerCase()) ? '✅' : '❌'}`);
      console.log(`- 后缀匹配: ${!config.suffix || address.toLowerCase().endsWith(config.suffix.toLowerCase()) ? '✅' : '❌'}`);
      console.log(`- 地址长度: ${address.length} 字符`);
      
      return {
        publicKey: address,
        secretKey: Array.from(keypair.secretKey),
        attempts,
        timeElapsed,
        difficulty,
        speed: Math.round(attempts / (timeElapsed / 1000))
      };
    }
    
    // 每5000次尝试显示进度
    if (attempts % 5000 === 0) {
      const currentTime = Date.now();
      const elapsed = currentTime - startTime;
      const speed = Math.round(attempts / (elapsed / 1000));
      const progress = (attempts / config.maxAttempts * 100).toFixed(2);
      
      console.log(`⏳ 尝试 ${attempts.toLocaleString()}/${config.maxAttempts.toLocaleString()} (${progress}%) - 速度: ${speed.toLocaleString()} 地址/秒`);
      
      lastLogTime = currentTime;
    }
    
    // 检查超时（5分钟）
    if (Date.now() - startTime > 300000) {
      console.log('\n⏰ 生成超时（5分钟），停止尝试');
      break;
    }
  }
  
  console.log('\n❌ 未能在指定尝试次数内生成靓号地址');
  console.log('💡 建议：');
  console.log('- 减少前缀/后缀长度');
  console.log('- 增加最大尝试次数');
  console.log('- 选择更简单的字符组合');
  
  return null;
}

/**
 * 批量生成示例
 */
async function generateMultiplePrettyAddresses() {
  console.log('🔥 批量生成靓号地址示例\n');
  
  const configs = [
    { prefix: '1', suffix: '', caseSensitive: false, maxAttempts: 50000 },
    { prefix: '12', suffix: '', caseSensitive: false, maxAttempts: 100000 },
    { prefix: '123', suffix: '', caseSensitive: false, maxAttempts: 200000 },
    { prefix: '', suffix: '88', caseSensitive: false, maxAttempts: 100000 },
    { prefix: 'A', suffix: 'Z', caseSensitive: true, maxAttempts: 150000 },
  ];
  
  for (let i = 0; i < configs.length; i++) {
    console.log(`\n📍 === 生成任务 ${i + 1}/${configs.length} ===`);
    const result = await generatePrettyAddress(configs[i]);
    
    if (result) {
      console.log(`✅ 任务 ${i + 1} 完成`);
    } else {
      console.log(`❌ 任务 ${i + 1} 失败`);
    }
    
    // 任务间隔
    if (i < configs.length - 1) {
      console.log('\n⏸️  等待 2 秒后开始下一个任务...');
      await new Promise(resolve => setTimeout(resolve, 2000));
    }
  }
  
  console.log('\n🏁 批量生成完成！');
}

/**
 * 难度估算工具
 */
function estimateDifficulties() {
  console.log('📊 靓号地址难度估算表\n');
  
  const testCases = [
    { prefix: '1', suffix: '', desc: '前缀1个字符' },
    { prefix: '12', suffix: '', desc: '前缀2个字符' },
    { prefix: '123', suffix: '', desc: '前缀3个字符' },
    { prefix: '1234', suffix: '', desc: '前缀4个字符' },
    { prefix: '12345', suffix: '', desc: '前缀5个字符' },
    { prefix: '', suffix: '1', desc: '后缀1个字符' },
    { prefix: '', suffix: '88', desc: '后缀2个字符' },
    { prefix: '', suffix: '999', desc: '后缀3个字符' },
    { prefix: '1', suffix: '1', desc: '前缀1个+后缀1个' },
    { prefix: '12', suffix: '34', desc: '前缀2个+后缀2个' },
  ];
  
  console.log('┌─────────────────────┬─────────────┬──────────────┬──────────────┐');
  console.log('│ 描述                │ 理论难度    │ 预估时间     │ 建议         │');
  console.log('├─────────────────────┼─────────────┼──────────────┼──────────────┤');
  
  testCases.forEach(testCase => {
    const difficulty = calculateDifficulty(testCase.prefix, testCase.suffix, false);
    const estimatedSeconds = Math.ceil(difficulty / 20000); // 假设每秒生成2万个地址
    
    let timeStr;
    if (estimatedSeconds < 60) {
      timeStr = `${estimatedSeconds}秒`;
    } else if (estimatedSeconds < 3600) {
      timeStr = `${Math.ceil(estimatedSeconds / 60)}分钟`;
    } else if (estimatedSeconds < 86400) {
      timeStr = `${Math.ceil(estimatedSeconds / 3600)}小时`;
    } else {
      timeStr = `${Math.ceil(estimatedSeconds / 86400)}天`;
    }
    
    let recommendation;
    if (difficulty <= 1000) {
      recommendation = '✅ 推荐';
    } else if (difficulty <= 100000) {
      recommendation = '⚠️  谨慎';
    } else {
      recommendation = '❌ 不建议';
    }
    
    const desc = testCase.desc.padEnd(17, ' ');
    const diffStr = difficulty.toLocaleString().padEnd(9, ' ');
    const timeStrPadded = timeStr.padEnd(10, ' ');
    
    console.log(`│ ${desc} │ ${diffStr} │ ${timeStrPadded} │ ${recommendation.padEnd(10, ' ')} │`);
  });
  
  console.log('└─────────────────────┴─────────────┴──────────────┴──────────────┘');
  
  console.log('\n💡 使用建议:');
  console.log('- ✅ 推荐：1-3个字符，几秒到几分钟即可完成');
  console.log('- ⚠️  谨慎：4-5个字符，可能需要几小时');
  console.log('- ❌ 不建议：6个字符以上，可能需要几天甚至更久');
  console.log('- 🔧 优化：使用多线程可以显著提升生成速度');
}

// 主函数
async function main() {
  const command = process.argv[2] || 'single';
  
  switch (command) {
    case 'single':
      console.log('🎯 单个靓号地址生成');
      await generatePrettyAddress(PRETTY_CONFIG);
      break;
      
    case 'batch':
      console.log('🔥 批量靓号地址生成');
      await generateMultiplePrettyAddresses();
      break;
      
    case 'estimate':
      console.log('📊 难度估算');
      estimateDifficulties();
      break;
      
    case 'custom':
      const prefix = process.argv[3] || '';
      const suffix = process.argv[4] || '';
      const caseSensitive = process.argv[5] === 'true';
      const maxAttempts = parseInt(process.argv[6]) || 100000;
      
      console.log('🎨 自定义靓号生成');
      await generatePrettyAddress({
        prefix,
        suffix,
        caseSensitive,
        maxAttempts
      });
      break;
      
    default:
      console.log('🎯 靓号地址生成工具');
      console.log('\n可用命令:');
      console.log('- single: 生成单个靓号地址');
      console.log('- batch: 批量生成多个靓号地址');
      console.log('- estimate: 查看难度估算表');
      console.log('- custom <前缀> <后缀> <区分大小写> <最大尝试次数>: 自定义生成');
      console.log('\n示例:');
      console.log('node scripts/pretty-address-generator.js single');
      console.log('node scripts/pretty-address-generator.js custom 123 "" false 200000');
      console.log('node scripts/pretty-address-generator.js estimate');
  }
}

if (require.main === module) {
  main().catch(console.error);
}

module.exports = {
  generatePrettyAddress,
  calculateDifficulty,
  validatePrettyAddress,
  estimateDifficulties
};
